home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-13
/
joe014.zip
/
JOE014.TAZ
/
JOE014.tar
/
asyncposix.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-01-23
|
6KB
|
300 lines
/* Terminal interface for POSIX
Copyright (C) 1991 Joseph H. Allen
(Contributed by Mike Lijewski)
This file is part of JOE (Joe's Own Editor)
JOE is free software; you can redistribute it and/or modify it under the terms
of the GNU General Public License as published by the Free Software
Foundation; either version 1, or (at your option) any later version.
JOE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
JOE; see the file COPYING. If not, write to the Free Software Foundation, 675
Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/time.h>
#include <sys/param.h>
#include <termios.h>
#include <unistd.h>
#include "async.h"
void tsignal();
#define DIVISOR 12000000
#define TIMES 2
static struct termios oldterm;
static unsigned char *obuf=0;
static unsigned obufp=0;
static unsigned obufsiz;
static unsigned long ccc;
static speed_t speeds[]=
{
B50,50,B75,75,B110,110,B134,134,B150,150,B200,200,B300,300,B600,600,B1200,1200,
B1800,1800,B2400,2400,B4800,4800,B9600,9600,EXTA,19200,EXTB,38400,B19200,19200,
B38400,38400
};
esignal(a,b)
void (*b)();
{
struct sigaction action;
sigemptyset(&actions.sa_mask);
action.sa_handler=b;
sigaction(a,&action,NULL);
}
sigjoe()
{
esignal(SIGHUP,tsignal);
esignal(SIGTERM,tsignal);
esignal(SIGPIPE,SIG_IGN);
esignal(SIGINT,SIG_IGN);
esignal(SIGQUIT,SIG_IGN);
}
signorm()
{
esignal(SIGHUP,SIG_DFL);
esignal(SIGTERM,SIG_DFL);
esignal(SIGQUIT,SIG_DFL);
esignal(SIGPIPE,SIG_DFL);
esignal(SIGINT,SIG_DFL);
}
aopen()
{
int x;
speed_t baud;
struct termios newterm;
fflush(stdout);
tcdrain(STDOUT_FILENO);
tcgetattr(STDIN_FILENO,&oldterm);
newterm=oldterm;
newterm.c_lflag&=0;
newterm.c_iflag&=~(ICRNL|IGNCR|INLCR);
newterm.c_oflag&=0;
newterm.c_cc[VMIN]=1;
newterm.c_cc[VTIME]=0;
tcsetattr(STDIN_FILENO,TCSANOW,&newterm);
ccc=0;
baud=cfgetospeed(&newterm);
for(x=0;x!=34;x+=2)
if(baud==speeds[x])
{
ccc=DIVISOR/speeds[x+1];
break;
}
if(obuf) free(obuf);
if(!(TIMES*ccc)) obufsiz=4096;
else
{
obufsiz=1000000/(TIMES*ccc);
if(obufsiz>4096) obufsiz=4096;
}
if(!obufsiz) obufsiz=1;
obuf=(unsigned char *)malloc(obufsiz);
}
aclose()
{
aflush();
tcsetattr(STDIN_FILENO,TCSANOW,&oldterm);
}
int have=0;
static unsigned char havec;
static int yep;
static void dosig()
{
yep=1;
}
aflush()
{
if(obufp)
{
struct itimerval a,b;
unsigned long usec=obufp*ccc;
if(usec>=500000/HZ)
{
a.it_value.tv_sec=usec/1000000;
a.it_value.tv_usec=usec%1000000;
a.it_interval.tv_usec=0;
a.it_interval.tv_sec=0;
action.sa_handler=dosig;
esignal(SIGALRM,dosig);
yep=0;
sigsetmask(sigmask(SIGALRM));
setitimer(ITIMER_REAL,&a,&b);
write(fileno(stdout),obuf,obufp);
while(!yep) sigpause(0);
esignal(SIGALRM,SIG_DFL);
}
else write(fileno(stdout),obuf,obufp);
obufp=0;
}
if(!have)
{
fcntl(STDIN_FILENO,F_SETFL,O_NDELAY);
if(read(STDIN_FILENO,&havec,1)==1) have=1;
fcntl(STDIN_FILENO,F_SETFL,0);
}
}
unsigned char *take=0;
anext()
{
if(take)
if(*take)
{
int c;
if(*take!='\\') return *take++;
++take;
if(!*take) return '\\';
else if(*take=='r') c='\r';
else if(*take=='b') c=8;
else if(*take=='n') c=10;
else if(*take=='f') c=12;
else if(*take=='a') c=7;
else if(*take=='\"') c='\"';
else if(*take>='0' && *take<='7')
{
c= *take++-'0';
if(*take>='0' && *take<='7')
{
c=c*8+*take++-'0';
if(*take>='0' && *take<='7') c=c*8+*take++-'0';
}
--take;
}
else c= *take;
++take;
return c;
}
else take=0;
aflush();
if(have) have=0;
else if(read(STDIN_FILENO,&havec,1)<1) tsignal(0);
if(record) macroadd(havec);
return havec;
}
eputc(c)
unsigned char c;
{
obuf[obufp++]=c;
if(obufp==obufsiz) aflush();
}
eputs(s)
char *s;
{
while(*s)
{
obuf[obufp++]= *(s++);
if(obufp==obufsiz) aflush();
}
}
getsize()
{
#ifdef TIOCGSIZE
struct ttysize getit;
#else
#ifdef TIOCGWINSZ
struct winsize getit;
#else
char *p;
#endif
#endif
#ifdef TIOCGSIZE
if(ioctl(fileno(stdout),TIOCGSIZE,&getit)!= -1)
{
if(getit.ts_lines>=3) height=getit.ts_lines;
if(getit.ts_cols>=2) width=getit.ts_cols;
}
#else
#ifdef TIOCGWINSZ
if(ioctl(fileno(stdout),TIOCGWINSZ,&getit)!= -1)
{
if(getit.ws_row>=3) height=getit.ws_row;
if(getit.ws_col>=2) width=getit.ws_col;
}
#else
if(p=getenv("ROWS")) sscanf(p,"%d",&height);
if(p=getenv("COLS")) sscanf(p,"%d",&width);
if(height<3) height=24;
if(width<2) width=80;
#endif
#endif
}
termtype()
{
unsigned char entry[1024];
unsigned char area[1024];
unsigned char *foo=area;
unsigned char *x=(unsigned char *)getenv("TERM");
if(!x) goto down;
if(tgetent(entry,x)!=1) goto down;
height=tgetnum("li");
if(height<3) height=24;
width=tgetnum("co");
if(width<2) width=80;
if(!tgetstr("cs",&foo)) scroll=0;
down:
getsize();
}
shell()
{
int x;
char *s=(char *)getenv("SHELL");
if(!s)
{
puts("\nSHELL variable not set");
return;
}
eputs("\nYou are at the command shell. Type 'exit' to continue editing\r\n");
aclose();
if(x=fork())
{
if(x!= -1) wait(0);
}
else
{
signorm();
execl(s,s,0);
_exit(0);
}
aopen();
}
susp()
{
#ifdef SIGCONT
eputs("\nThe editor has been suspended. Type 'fg' to continue editing\r\n");
yep=0;
aclose();
esignal(SIGCONT,dosig);
sigsetmask(sigmask(SIGCONT));
kill(0,SIGTSTP);
while(!yep) sigpause(0);
esignal(SIGCONT,SIG_DFL);
aopen();
#else
shell();
#endif
}